Welcome.
In this lecture, we'll be exploring object oriented programming and Roblox.
Luigi using tables and meta tables.
If this is a new concept to you or one you're not completely familiar with, don't worry, we're going
to be learning about it more in this lecture.
Object Oriented Programming, or OOP for short, is a programming paradigm that is based on the concept
of objects.
In object oriented programming, an object is an instance of a class, which is a blueprint for creating
objects.
These objects can have attributes or properties and behaviors or methods that define their functionality.
As an example, think of a blueprint for creating a car.
One blueprint exists, but from that blueprint we can make as many cars as we want.
Now in Roblox Lua, we can use tables and meta tables to simulate objects and classes.
By using tables, we can define the class for an object in conjunction with module scripts.
From that point, we can use that table as a helper table or meta table to define the functionality
for the other table.
When we add tables together, subtract tables, call tables, and so on.
The main goal of object oriented programming is to make your code more readable and scalable.
In object oriented programming, there is usually a keyword in the language for creating a class.
However, since Lua is a functional language, there is no class keyword for creating classes, so we
have to imitate classes by using tables instead of studio.
Here I'll give a very basic example of a class and objects we can create from it.
For example, if we wanted an enemy on a game, we could create a variable called enemy and it can be
equal to a table.
Inside of this table, we can set some properties that all enemies in our game would have, like name
health.
Damage, speed and so on.
We can also define a function this class will have that these enemies can use like attack.
This table is now acting as our class, which means we can create a new table.
I'm going to call it Goblin.
And then we can set the meta table for our Goblin cable to be the enemy class.
Because the enemy class is now our helper table.
Anytime we call the goblin table or index the table, or use addition and subtraction on the table.
If our helper table has any defined functionality for those events, they will be used.
So basically, in order for me to access the properties for my goblin that were originally defined within
the class itself, I have to define a meta method in my enemy table for when it is indexed, and meta
method is simply just a special function that defines the behavior for a table.
When a specific context or operation happens, a meta method is declared by creating a key value pair
in our enemy table, and the one I'll be creating here is called underscore underscore index, and I'll
set it to be equal to the class itself.
What did this do?
Well, any time we create a table and the enemy table is attached to it as a helper table, if we were
to index the original table for a key that did not exist within it, then it will go and check the meta
table to see if it has an underscore underscore index meta method.
If it does, then it will go through and check to see if that key exists within the table that was supplied
to the meta method.
This is how we will be able to access the properties that we originally defined within the enemy table.
Now I'm able to access the properties like health and I can set it to whatever I like.
I can also index and call the functions that exist within the meta table two directly on our original
Goblin.
And since I'm calling this function directly on the table, it's automatically passed to the function
as a variable called self.
Self is another keyword that exists within a function that is called with a colon, and because it's
automatically passed, I don't need to define it in the parameters section of my function.
So in my attack function I can print something like a string the concatenated with self dot name, concatenate
it with, attacked with, concatenate it with self dot damage, and then concatenate it with the string
damage.
And we can set the name and damage of our goblin.
Now we can run the game and it should print the goblin attack with 50 damage in the console.
Perfect.
It printed what we expected.
Now, there was another way of creating objects from our class, and that's using a function called
a constructor, which is just a name for a function that creates the objects for us.
Inside of our enemy class, we can define a new function called dot new, and we can pass several arguments
to the function that we will set up for the properties in the object, like the name, the health,
the damage, and the speed.
From that point, we can create a new table within this function, and I'll call it self, and it'll
be equal to the return from the set meta table function.
We will create a new table in this function and attach the enemy class to it as the meta table.
Now we can set all the properties for self.
And then we can return self back to where this function was called.
Now that we have this function defined, we can delete our previous code and use this new function instead.
We can pass the same properties to this constructor like the name health.
Damage and speed, and then we can call the attack function on the variable that gets returned from
this function.
And we should get the exact same output in the console as before.
And just like that, we get what we expected.
As you can see, this is how we can imitate classes and objects in Lua.
In the next lectures, we'll be taking a look at some more core principles of object oriented programming
and how we use module scripts to act as classes.
I hope to see you there.